/*******************************************************************************
 * Copyright (c) 2011, 2013 EclipseSource and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    EclipseSource - initial API and implementation
 ******************************************************************************/
package it.rap.applications.container.internal;

import it.rap.applications.container.IContainerContribution;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


public final class Containers {

  private static final List<ContainerCategory> EXAMPLE_CATEGORIES = createCategories();
  private static final String OFF = "off";
  private static final String ON  = "on";
  
  private Containers() {
  }

  public static Containers getInstance() {
    return new Containers();
  }

  public List<ContainerCategory> getCategories() {
    return Collections.unmodifiableList( EXAMPLE_CATEGORIES );
  }

  public IContainerContribution getContribution( String id ) {
    return getContributionsTracker().getContribution( id );
  }

  public IContainerContribution findInitialContribution() {
    IContainerContribution contribution = null;
    List<ContainerCategory> categories = getInstance().getCategories();
    if( !categories.isEmpty() ) {
      contribution = Containers.getFirstContribution( categories.get( 0 ) );
    }
    return contribution;
  }

  private static IContainerContribution getFirstContribution( ContainerCategory category ) {
    IContainerContribution contribution = null;
    List<String> contributionIds = category.getContributionIds();
    if( !contributionIds.isEmpty() ) {
      contribution = getInstance().getContribution( contributionIds.get( 0 ) );
    }
    return contribution;
  }

  private static ContainerContributionsTracker getContributionsTracker() {
    return Activator.getDefault().getExampleContributions();
  }

  // TODO [rst] Read from configuration file
  private static List<ContainerCategory> createCategories() {
    List<ContainerCategory> containerCategories = new ArrayList<ContainerCategory>();
    
    
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(false);
    factory.setIgnoringElementContentWhitespace(true);
    try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputStream input = Containers.class.getClassLoader().getResourceAsStream( "it/rap/applications/container/internal/config/categories.xml" );

        Document doc = builder.parse( input );
        doc.getDocumentElement().normalize();
        
    	System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
    	
    	NodeList nList = doc.getElementsByTagName("category");
    	if ( nList != null ){
	    	for (int i = 0; i < nList.getLength(); i++) {
	    		ContainerCategory category = null;
	    		Node nNode = nList.item(i);    		
	    		if (nNode.getNodeType() == Node.ELEMENT_NODE) {    			 
	    			Element eElement = (Element) nNode;     
	    			String elementState =  eElement.getAttribute("state");
	    			if ( elementState != null && ON.equalsIgnoreCase( elementState ) ){
	    				category = new ContainerCategory( eElement.getAttribute("name") );
	    				
	    				NodeList nCat = eElement.getElementsByTagName("item");
	    				for (int y = 0; y < nCat.getLength(); y++) {
	    					Node catNode = nCat.item(y);    
	    				
	    					if (catNode.getNodeType() == Node.ELEMENT_NODE) { 
	    						Element cElement = (Element) catNode;     
	    		    			String cElementState =  cElement.getAttribute("state");
	    		    			if ( cElementState != null && ON.equalsIgnoreCase( cElementState ) &&  cElement.getAttribute("name" ) != null && !"".equals( cElement.getAttribute("name" ) ) ){
	    		    				category.addContributionId( cElement.getAttribute("name" ) );    		    				
	    		    			}
	    					}
	    				}
	    				
	    			}    			     
	    		}
	    		if ( category != null  ){
	    			containerCategories.add( category );
	    		}
	    	}
    		
    	}
     
    } catch (ParserConfigurationException e) {
    } catch (SAXException e) {
    } catch (IOException e) { 
    }
    
    /*
    containerCategories.add( createCategory( "Account",
    		"it.rap.applications.movimenti.ricerche", "it.rap.applications.filters", "report", "it.rap.applications.property.manager", "it.rap.applications.birt.chart", "it.rap.applications.birt.report", "it.rap.applications.birt.report.accounts") );
    
    containerCategories.add( createCategory( "Basic Widgets",
                                           "it.rap.applications.sara","input", "button", "canvas", "dialog") );
    containerCategories.add( createCategory( "Trees & Tables", "tableviewer", "treeviewer",
                                           "table-markup", "table-template" ) );
    containerCategories.add( createCategory( "Key Features",
                                           "complex-data", "rich-label", "validation",
                                           "drag-and-drop", "file-upload", "nls" ) );
    containerCategories.add( createCategory( "Layouts",
                                           "grid-layout", "row-layout", "fill-layout" ) );
    containerCategories.add( createCategory( "Custom Widgets",
                                           "gmaps", "ckeditor", "oscilloscope", "carousel", "chart",
                                           "nebula-grid", "drop-down" ) );
                                           */
    return containerCategories;
  }

  private static ContainerCategory createCategory( String name, String... contributions ) {
    ContainerCategory exampleCategory = new ContainerCategory( name );
    for( String contribution : contributions ) {
      exampleCategory.addContributionId( contribution );
    }
    return exampleCategory;
  }

}
